home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
emulator
/
bsvc-1.000
/
bsvc-1
/
bsvc-1.0.4
/
src
/
Assemblers
/
hecasm
/
emit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-26
|
3KB
|
167 lines
/* this routine is paired with lex.c. They do arithmetic expression */
/* analysis in agreement with operator precedence. The general idea */
/* is that expressions are tokenized and converted to post fix and */
/* placed in a buffer until the entire expression is there. Then it */
/* is evaluated and the result returned */
#include "asm.h"
#include "global.h"
/* place the token from the lexer in a buffer */
emit(t)
int t;
{
switch(t)
{
case NUM:
/* integer */
opq[optop++] = token;
break;
case ID:
/* symbol */
opq[optop++] = token;
break;
default:
/* an operator */
opq[optop].type = NONE;
opq[optop++].uval.ival = t;
break;
}
}
/* evaluate the post fix expression stored in the buffer */
/* this is called when the expression is collected */
post()
{
int i;
/* proceed down the buffer */
for(i=0;i<optop;i++)
{
/* if it is an integer push its value on a stack */
if (opq[i].type == NUM)
push(opq[i].uval.ival);
/* if it is a variable lookup its value and push it on the stack */
else if (opq[i].type == ID)
{
if (oklookup(&opq[i]))
push(opq[i].uval.sval->s_value);
else
/* symbol is undefined */
{
push(0);
undefined = TRUE;
}
}
else
/* it is an operator so evaluate some of the stack */
perform(opq[i].uval.ival);
}
/* pop the last value off the stack and return it */
pop(&i);
return(i);
}
/* see if the symbol is defined */
oklookup(ptr)
vtype *ptr;
{
if (ptr->uval.sval->s_type & S_VALID)
return(TRUE);
if (ptr->uval.sval->s_type == S_UND)
err('u',"undefined symbol");
return(FALSE);
}
/* evaluate an operator */
perform(op)
int op;
{
int v1, v2;
/* pop the first argument */
pop(&v2);
/* see if it is a single operand operator */
switch(op)
{
case NE:
push(-v2);
return;
case CO:
push(~v2);
return;
case NG:
push(!v2);
return;
}
/* it must require two operands so pop another */
pop(&v1);
switch(op)
{
case PL:
push(v1 + v2);
break;
case MI:
push(v1 - v2);
break;
case MU:
push(v1 * v2);
break;
case DI:
push(v1 / v2);
break;
case AN:
push(v1 & v2);
break;
case OR:
push(v1 | v2);
break;
case XO:
push(v1 ^ v2);
break;
default:
err('u',"undefined operator");
}
}
/* evaluation stack and stack pointer */
int stack[STSIZE];
int tos = 0;
/* push a value on the stack and check for overflow */
push(val)
int val;
{
if (tos == STSIZE)
{
err('v',"expression stack overflow");
exit(0);
}
stack[tos++] = val;
}
/* pop a value off the stack and check for underflow */
pop(aval)
int *aval;
{
if (tos == 0)
err('U',"expression stack underflow");
else
*aval = stack[--tos];
}